﻿using System;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace RG.Common.WPF.Wizard
{
    public interface IWizardVM
    {
        ObservableCollection<IWizardPage> Pages { get; }
        IWizardPage CurrentPage { get; set; }
        ICommand NextCmd { get; set; }
        ICommand BackCmd { get; set; }
        string ErrorText { get; set; }
    }

    public interface IWizardPage
    {
        /// <summary>
        /// Ссылка на Wizard в котором показывается страница. ВНИМАНИЕ ! Использовать только в крайних случаях
        /// </summary>
        IWizardVM ParentWizardVM { get; set; }
        string Caption { get; }
        string NextCaption { get; set; }
        bool CanNext { get; }
        bool CanBack { get; }

        /// <summary>
        /// Валидно ли то что на выходе, используется когда ходим в базу, чтобы проверить
        /// </summary>
        bool IsOutputValid { get; set; }
        /// <summary>
        /// Текст ошибки, если не валидно
        /// </summary>
        string ErrorText { get; set; }


        void AfterFinish();

        void Init(object input);
        object Finish();
        Type GetNextPage();
        Type GetPreviousPage();
    }

    public abstract class  WizardPageVM<TIn, TOut> : IWizardPage
    {
        public IWizardVM ParentWizardVM { get; set; }

        public string Caption { get; set; }
        public string NextCaption { get; set; }

        public bool IsOutputValid { get; set; }

        public string ErrorText { get; set; }

        public bool CanNext { get { return OnCanNext(); } }
        public bool CanBack { get { return OnCanBack(); } }

        public Func<bool> OnCanNext;
        public Func<bool> OnCanBack;

        public void Init(object input)
        {
            OnInit((TIn)input);
        }



        public object Finish()
        {
            return OnFinish();
        }

        public virtual void AfterFinish()
        {
            
        }

        public virtual Type GetNextPage()
        {
            return null;
        }

        public virtual Type GetPreviousPage()
        {
            return null;
        }

        public virtual void OnInit(TIn input)
        {
            Input = input;
        }

        public virtual TOut OnFinish()
        {
            return Output;
        }

        public TIn Input { get; set; }
        public TOut Output { get; set; }

        protected WizardPageVM()
        {
            OnCanBack = () => true;
            OnCanNext = () => true;
            NextCaption = "Далее";
            IsOutputValid = true;
        }
    }
}
